package com.da.javatest.thread.juc.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

/**
 * @author chenlida
 * @date 2020/7/12 16:58
 *
 * 1.内部有一个人把规则破坏了（接收到中断信号），其他人都不按规则来了，不会等待了
 * 2.接收到中断信号的线程，await方法会触发InterruptedException异常，然后被唤醒向下运行
 * 3.其他等待中 或者后面到达的线程，会在await()方法上触发`BrokenBarrierException`异常，然后继续执行
 */
public class CyclicBarrier3 {
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    public static class MyThread extends Thread {
        private int sleep;

        public MyThread(String name, int sleep) {
            super(name);
            this.sleep = sleep;
        }

        @Override
        public void run() {
            long starTime = 0, endTime = 0;
            try {
                //模拟休眠
                TimeUnit.SECONDS.sleep(sleep);
                starTime = System.currentTimeMillis();
                //调用await()的时候，当前线程将会被阻塞，需要等待其他员工都到达await了才能继续
                System.out.println(this.getName() + "到了！");
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
            endTime = System.currentTimeMillis();
            System.out.println(this.getName() + ",sleep:" + this.sleep + " 等待了" + (endTime - starTime) + "(ms),开始吃饭了！");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i <= 5; i++) {
            int sleep = 0;
            if (i == 5) {
                sleep = 5;
            }
            MyThread myThread = new MyThread("员工" + i, sleep);
            myThread.start();
            if (i == 3) {
                //模拟员工3接了个电话，将自己等待吃饭给打断了
                TimeUnit.SECONDS.sleep(1);
                System.out.println(myThread.getName() + ",有点急事，我先开干了！");
                myThread.interrupt();
                TimeUnit.SECONDS.sleep(2);
            }
        }
    }
}
